/**
 * 给定数组，问区间第几众数，注意要是有数量相同的，要直接回答最大的
 * 1 1 2 2 3
 * 1 4 1
 * 1 4 2
 * 1 4 3
 * 因为1和2的次数是样多的，因此第1众数与第2众数都是2, 第3众数则是3
 * N在5E4，很明显莫队算法，增加和删除都可以在log时间完成。主要是查询操作
 * 本代码是仿照首A代码写的，用加法，不会算均摊，也许也是log。
 * 赛时使用了pbds::tree，查询也是log，但是T了
 * 后来使用树状数组上二分，还是T了。
 */
#include <bits/stdc++.h>
using namespace std;

#include <bits/extc++.h>
using namespace __gnu_pbds;

struct mo_t{ // 莫队算法无修改, 依次调用input(),run(),output()

struct query_t{
    int s;
    int e;
    int idx;
    int k;
    bool operator < (const query_t & b) const {
        int ln = s / block_size();
        int rn = b.s / block_size();
        if(ln != rn) return ln < rn;
        return e < b.e;
    }
};

using value_t = int;
using answer_t = int;

vector<value_t> data;      // 原始数组
vector<query_t> questions; // 问题
vector<answer_t> ans;      // 答案

vector<int> W;
vector<int> Cnt;
map<int, set<int>> cnt2val;
set<int> hascnt;
vector<int> numofcnt;

int curLeft, curRight;

static int block_size() {
    static int const BLOCK_SIZE = 225;
    return BLOCK_SIZE;
}

void init(){
    sort(questions.begin(), questions.end());

    curLeft = 1; curRight = 0;

    cnt2val.clear();
    hascnt.clear();
    Cnt.assign(data.size() + 1, 0);    
    ans.assign(questions.size(), 0);
    numofcnt.assign(data.size() + 1, 0);
}

void insert(int idx){
    auto v = data[idx];
    auto c = ++Cnt[v];
    if(c != 1){
        --numofcnt[c - 1];
        cnt2val[c - 1].erase(v);
        if(0 == numofcnt[c - 1]){
            cnt2val.erase(c - 1);
        }
    }
    ++numofcnt[c];
    cnt2val[c].insert(v);
}

void remove(int idx){
    auto v = data[idx];
    auto c = --Cnt[v];    

    cnt2val[c + 1].erase(v);
    if(0 == --numofcnt[c + 1]){
        cnt2val.erase(c + 1);
    }

    if(c){
        ++numofcnt[c];
        cnt2val[c].insert(v);
    }
}

answer_t answer(int k){
    int ans = 0;
    for(auto it=cnt2val.rbegin(),et=cnt2val.rend();it!=et;++it){
        k -= it->second.size();
        ans = *it->second.rbegin();
        if(k <= 0) break;
    }
    return ans;
}

void input(){
    int n, q; cin >> n >> q;
    data.assign(n + 1, 0);
    W.assign(n + 1, 0);
    for(int i=1;i<=n;++i){
        cin >> data[i];
        W[i] = data[i];
    }

    sort(W.begin(), W.end());
    W.erase(unique(W.begin(), W.end()), W.end());

    for(auto & i : data){
        i = lower_bound(W.begin(), W.end(), i) - W.begin();
    }

    questions.assign(q, {});
    int k = 0;
    for(auto & q : questions){
        cin >> q.s >> q.e >> q.k;
        q.idx = k++;
    }

    return;
}

void run(){
    init();

    int k = 0;
    for(const auto & q : questions){
        while(curRight < q.e) insert(++curRight);
        while(curLeft > q.s) insert(--curLeft);
        while(curRight > q.e) remove(curRight--);
        while(curLeft < q.s) remove(curLeft++);
        // cout << ++k << endl;
        ans[q.idx] = W[answer(q.k)];
    }
}

void output(){
    for(auto i : ans) cout << i << endl;
    // cout << endl;
}

};

mo_t Mo;

int main(){
#ifndef ONLINE_JUDGE
    freopen("z.txt", "r", stdin);
#endif
    ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(0);
    Mo.input();
    Mo.run();
    Mo.output();
    return 0;
}